import Layout from '@/components/f-layout/f-layout'

// 模拟的数据
// const FPermission = [
//   {
//     path: '/index',
//     component: 'components/f-layout/f-layout',
//     name: 'index',
//     redirect: 'noRedirect',
//     children: [{
//       path: 'index',
//       component: 'pages/index/index',
//       name: 'index/index',
//       meta: {
//         title: '首页',
//         icon: 'el-icon-eleme', // 图标
//         roles: ['admin', 'editor'] // 或者你可以给每一个子路由设置自己的权限
//       }
//     }]
//   }, {
//     path: '/system',
//     component: 'components/f-layout/f-layout',
//     name: 'system',
//     redirect: '/system/user',
//     meta: {
//       title: '系统管理',
//       icon: 'el-icon-eleme', // 图标
//       roles: ['admin', 'editor'] // 或者你可以给每一个子路由设置自己的权限
//     },
//     children: [{
//       path: 'user',
//       component: 'pages/system/user/index',
//       name: 'system/user',
//       meta: {
//         title: '用户管理',
//         icon: 'el-icon-eleme', // 图标
//         roles: ['admin', 'editor'] // 或者你可以给每一个子路由设置自己的权限
//       }
//     }, {
//       path: 'dept',
//       component: 'pages/system/dept/index',
//       name: 'system/dept',
//       meta: {
//         title: '部门管理',
//         icon: 'el-icon-eleme', // 图标
//         roles: ['admin', 'editor'] // 或者你可以给每一个子路由设置自己的权限
//       }
//     }]
//   }, {
//     path: 'https://www.baidu.com',
//     name: 'system/baidu',
//     meta: {
//       title: '百度',
//       icon: 'el-icon-eleme', // 图标
//       roles: ['admin', 'editor'] // 或者你可以给每一个子路由设置自己的权限
//     }
//   }
// ]
// 定义路由数据 用于动态加载
const permissionRouter = {
  // state vuex的基本数据，用来存储变量
  state: {
    routes: []
  },
  // mutations 提交更新数据的方法，必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.routes = routes
    }
  },
  // actions 和mutation的功能大致相同，不同之处在于 ==》1. Action 提交的是 mutation，而不是直接变更状态。 2. Action 可以包含任意异步操作。
  actions: {
    generateRoutes ({commit}, accessedRoutes) {
      // promise是一个对象，对象和函数的区别就是对象可以保存状态，函数不可以（闭包除外）
      return new Promise(resolve => {
        commit('SET_ROUTES', accessedRoutes)
        // resolve作用是，将Promise对象的状态从“未完成”变为“成功”（即从 pending 变为 resolved），在异步操作成功时调用，并将异步操作的结果，作为参数传递出去；
        // reject作用是，将Promise对象的状态从“未完成”变为“失败”（即从 pending 变为 rejected），在异步操作失败时调用，并将异步操作报出的错误，作为参数传递出去。
        resolve(accessedRoutes)
      })
    }
  }
}

// 验证路由中是否存在资源
function hasPermission (roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

// 设置路由跳转地址
export const loadPages = (page) => {
  return () => import(`@/${page}`)
}

// 过滤路由 解析地址import
export const filterAsyncRouter = (routers, roles) => {
  const res = [] // 用于存储返回的路由根据角色
  return routers.filter(rt => { // 遍历菜单路由
    if (roles.includes('admin') || hasPermission(roles, rt)) {
      if (rt.component === 'Layout') { // Layout组件特殊处理
        rt.component = Layout
      } else if (rt.component) {
        const component = rt.component
        rt.component = loadPages(component)
      }
      if (rt.children && rt.children.length) {
        rt.children = filterAsyncRouter(rt.children, roles)
      }
    }
    res.push(rt)
    return true
  })
}

export default permissionRouter
